var request = require('request');
var qs = require('querystring');
var crypto = require('crypto');

//var PARSE_HOST = 'http://120.26.134.103:1337';
//var PARSE_HOST = 'https://parse.lovepinyao.com';
var PARSE_HOST = 'http://192.168.1.9:1337';
var WEIXIN_LOGIN = 'http://parse.lovepinyao.com/redirectWX';

var WXOauth = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' +
    'wx966722d472a4146d&' +
    'redirect_uri=http%3A%2F%2F'+ WEIXIN_LOGIN +'%2FwxLogin&' +
    'response_type=code&' +
    'scope=snsapi_userinfo&' +
    'state=seagou#' +
    'wechat_redirect';

var PARSE_HEADERS = {
    'Content-Type': 'application/json;charset=utf-8',
    'X-Parse-Application-Id': 'myAppId',
    'X-Parse-Master-Key': 'masterKey'
};

var JADE_VAR = {
    __BOWER_ROOT__: '/bower_components',
    __IMAGE_HOST__ : 'http://7xlaxq.com1.z0.glb.clouddn.com/'
};

var getWeiXinOAuthUrl = function(stateType){
    return 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' +
        'wx966722d472a4146d&' +
        'redirect_uri=http%3A%2F%2F'+ WEIXIN_LOGIN +'%2FwxLogin&' +
        'response_type=code&' +
        'scope=snsapi_userinfo&' +
        'state=seagou_'+ stateType + '#wechat_redirect';
};

var apiRequest = function (url) {
    return new Promise(
        function (resolve, reject) {
            request(url, function (error, response, body) {
                if (error) {
                    reject(error);
                } else {
                    try {
                        var responseJSON = JSON.parse(body);
                    } catch (e) {
                        reject(error);
                    }
                    resolve(responseJSON);
                }
            });
        }
    );
};

var apiParseRequest = function (method, path, params, X_Session_Token) {
    var paramsStr = JSON.stringify(params);
    var options = {
        url: PARSE_HOST + path,
        method: method,
        body: paramsStr,
        form:params,
        headers: PARSE_HEADERS
    };
    if (X_Session_Token) {
        options.headers['X-Parse-Session-Token'] = X_Session_Token;
    }
    return new Promise(
        function (resolve, reject) {
            request(options, function (error, response, body) {
                if (error) {
                    reject(error);
                } else {
                    try {
                        //console.log(body);
                        var responseJSON = JSON.parse(body);
                        var results = undefined;
                        if(path.indexOf('parse/') != -1){
                            resolve(responseJSON);
                            return;
                        }
                        if (responseJSON.code == 200) {
                            results = responseJSON.results;
                        }
                        resolve(results);
                    } catch (e) {
                        reject(error);
                    }
                }
            });
        }
    )
};


var getNowFormatDate = function () {
    var day = new Date();
    var Year = 0;
    var Month = 0;
    var Day = 0;
    var CurrentDate = "";
    Year = day.getFullYear();//ie火狐下都可以
    Month = day.getMonth() + 1;
    Day = day.getDate();
    CurrentDate += Year + "-";
    if (Month >= 10) {
        CurrentDate += Month + "-";
    }
    else {
        CurrentDate += "0" + Month + "-";
    }
    if (Day >= 10) {
        CurrentDate += Day;
    }
    else {
        CurrentDate += "0" + Day;
    }
    return CurrentDate;
};

var getUserId = function (req) {
    return req.session.userId ? req.session.userId : req.query.userId ? req.query.userId : req.body.userId ? req.body.userId : '';
};

var getRes = function(code,msg,data,isViews){

    var results = {
        code:code,
        message:msg
    };
    if(isViews){
        results.JADE_VAR = getJADEVAR();
    }
    if(data){
        results.results = data;
    }
    return results;
};

function Base64() {

    // private property
    _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    // public method for encoding
    this.encode = function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;
        input = _utf8_encode(input);
        while (i < input.length) {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output = output +
                _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
                _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
        }
        return output;
    };

    // public method for decoding
    this.decode = function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
        while (i < input.length) {
            enc1 = _keyStr.indexOf(input.charAt(i++));
            enc2 = _keyStr.indexOf(input.charAt(i++));
            enc3 = _keyStr.indexOf(input.charAt(i++));
            enc4 = _keyStr.indexOf(input.charAt(i++));
            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;
            output = output + String.fromCharCode(chr1);
            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }
        }
        output = _utf8_decode(output);
        return output;
    };

    // private method for UTF-8 encoding
    _utf8_encode = function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";
        for (var n = 0; n < string.length; n++) {
            var c = string.charCodeAt(n);
            if (c < 128) {
                utftext += String.fromCharCode(c);
            } else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            } else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }
        return utftext;
    };

    // private method for UTF-8 decoding
    _utf8_decode = function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;
        while ( i < utftext.length ) {
            c = utftext.charCodeAt(i);
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            } else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            } else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
        return string;
    }
}

// private method for UTF-8 decoding
function _utf8_encode(string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";
    for (var n = 0; n < string.length; n++) {
        var c = string.charCodeAt(n);
        if (c < 128) {
            utftext += String.fromCharCode(c);
        } else if((c > 127) && (c < 2048)) {
            utftext += String.fromCharCode((c >> 6) | 192);
            utftext += String.fromCharCode((c & 63) | 128);
        } else {
            utftext += String.fromCharCode((c >> 12) | 224);
            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
            utftext += String.fromCharCode((c & 63) | 128);
        }

    }
    return utftext;
}


var validateRequest = function( params,callback ){
    if(!params.sign){
        callback(0,"非法访问");
        return;
    }
    if(!params.timeStr){
        callback(0,"非法访问");
        return;
    }

    //过期检测
    var requestTimeStamp = new Date().getTime();
    if(requestTimeStamp - params.timeStr > 5*60*1000){
        callback(0,"请求过期");
        return;
    }
    var signStr = params.sign;
    //然后将除sign以外的参数升序排列后拼接
    var keys = Object.keys(params).sort();
    var waitSign = '';
    keys.forEach(function(i){
        if(params[i] && i != 'sign'){
            waitSign += _utf8_encode(String(params[i]));
        }
    });
    //检查生成参数列
    if(!waitSign){
        callback(-2,"核验字段错误");
        return;
    }
    //生成本地签名
    var localSign = crypto.createHash('md5').update(waitSign).digest('hex');
    //if(localSign != signStr){
    //    callback(3,"签名不通过");
    //}else{
    //    callback(1,"请求成功");
    //}
    callback(1,"请求成功");
};

var getUserOpenIdByUid = function (uid) {
    return apiParseRequest('POST','/parse/functions/getUserOpenId',{userId:uid})
};

var getJADEVAR = function () {
    return {
        __PLUGINS_ROOT__: '/public/plugins',
        __BOWER_ROOT__: '/bower_components',
        __IMAGE_HOST__ : 'http://7xlaxq.com1.z0.glb.clouddn.com/'
    };
};

module.exports = {
    JADE_VAR: JADE_VAR,
    WXOauth: WXOauth,
    WEIXIN_LOGIN:WEIXIN_LOGIN,
    getJADEVAR:getJADEVAR,
    apiParseRequest: apiParseRequest,
    getNowFormatDate: getNowFormatDate,
    apiRequest: apiRequest,
    getUserId:getUserId,
    getRes:getRes,
    base64Assert:Base64,
    validateRequest:validateRequest,
    getUserOpenIdByUid:getUserOpenIdByUid,
    getWeiXinOAuthUrl:getWeiXinOAuthUrl
};